#include "Session.h"
#include <cstring>
#include <functional>
#include <iostream>
#include "Server.h"
#include "boost/uuid/uuid.hpp"
#include "boost/uuid/uuid_generators.hpp"
#include "boost/uuid/uuid_io.hpp"

Session::Session(boost::asio::io_context& io_context,Server *server)
: socket_(io_context),server_(server)
{
    boost::uuids::uuid a_uuid = boost::uuids::random_generator()();
    uuid_ = boost::uuids::to_string(a_uuid);
}

Session::~Session()
{
    std::cout << "Session::~Session" << std::endl;
}

void Session::Start()
{
    memset(_data, 0, sizeof(_data));
    socket_.async_read_some(boost::asio::buffer(_data,sizeof(_data)),
        std::bind(&Session::HandleRead, this, std::placeholders::_1, std::placeholders::_2,shared_from_this()));
}


void Session::HandleRead(const boost::system::error_code &ec,
        std::size_t bytes_transferred,std::shared_ptr<Session> session)
{
    if(ec)
    {
        std::cout << "HandleRead error error value: " << ec.value() << " message: " << ec.message() << std::endl;
        server_->ClearSession(uuid_);
        return;
    }
    Send(_data,bytes_transferred);
    memset(_data, 0, sizeof(_data));
    //服务器将收到的数据发送给客户端
    socket_.async_read_some(boost::asio::buffer(_data,MAX_LENGTH),std::bind(&Session::HandleRead,
                                                                     this, std::placeholders::_1, 
                                                                    std::placeholders::_2,shared_from_this()));
    
    
}

void Session::HandleWrite(const boost::system::error_code &ec,std::shared_ptr<Session> session)
{
    if(ec)
    {
        std::cout << "HandleWrite error error value: " << ec.value() << " message: " << ec.message() << std::endl;
        server_->ClearSession(uuid_);
        return;
    }
    //发送下一条数据
    std::lock_guard<std::mutex> lock(_send_lock);
    _send_queue.pop();
    if(!_send_queue.empty())
    {
        auto msgNode = _send_queue.front();
        //服务器继续等待下一次读取
        boost::asio::async_write(socket_,boost::asio::buffer(msgNode->_msg+msgNode->_cur_len,
                                    msgNode->_total_len-msgNode->_cur_len),
                                    std::bind(&Session::HandleWrite, this, std::placeholders::_1,shared_from_this()));
    }
}


void Session::Send(char*msg,int max_length)
{
    auto msgNode = std::make_shared<MsgNode>(msg,max_length);
    std::lock_guard<std::mutex> lock(_send_lock);
    //    加入发送队列
    _send_queue.push(msgNode);
    //    如果是第一个数据，直接发送
    if(_send_queue.size() == 1)
    {
        msgNode = _send_queue.front();
        boost::asio::async_write(socket_,boost::asio::buffer(msgNode->_msg+msgNode->_cur_len,
                                    msgNode->_total_len-msgNode->_cur_len),
                                    std::bind(&Session::HandleWrite, this, std::placeholders::_1,shared_from_this()));
    }

}